Skip to main content

第 2 章:運行 playbook 環境配置

如何運行 playbook

使用 ansible-playbook $PLAYBOOK 的指令就可以運行編寫好的 playbook

ansible-playbook playbook.yml

執行完畢後我們應該可以在終端機上看到以下的輸出:

PLAY RECAP *********************************************************************

配置 inventory file

playbook.yml
---
- hosts: server
tasks:
# task 1
- name: test connection
ping:
register: message

# task 2
- name: print debug message
debug:
msg: "{{ message }}"

server 這台主機進行任務清單中定義的任務。定義一個目錄 (inventory) 讓 Ansible 參照,這樣 Ansible 才會知道該對哪一台主機做什麼事。

為了知道 server 這台主機的詳細資料,我們可以透過 vagrant ssh-config 這個指令來列出主機的相關資訊。

vagrant ssh-config
Host server
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/tsoliang/Desktop/workspace/.vagrant/machines/server/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL

接著新增一個檔案並命名為 inventory ,然後在檔案內寫入以下內容

[server]
127.0.0.1 ansible_port=2222 ansible_user=vagrant

根據 vagrant ssh-config 列出來的主機資訊,我們在 inventory 中依序定義了 server 這台主機的連線 IP、port 入口以及登入使用者的身份。現在,讓我們重新執行運行指令,並將這份主機清單指定給 Ansible 參照

ansible-playbook -i inventory playbook.yml
PLAY [server] ******************************************************************

TASK [setup] *******************************************************************
fatal: [127.0.0.1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n", "unreachable": true}
to retry, use: --limit @/Users/tsoliang/Desktop/workspace/playbook.retry

PLAY RECAP *********************************************************************
127.0.0.1 : ok=0 changed=0 unreachable=1 failed=0

透過 inventory file 的配置,我們可以輕易的將不同部署環境做有系統的整理。舉例來說,在軟體開發實務上根據開發階段的不同,我們常常會有多種不同的部署環境,好比說最常見的 testing、development 以及 production。其中,每個環境可能又有不止一台的主機需要被維護,因此我們可以將每個環境需要配置的細節清楚定義在不同的 inventory file 中,然後透過類似以下指令來透過 Ansible 真正實現一鍵部署

ansible-playbook -i devl-inventory devl-playbook.yml
ansible-playbook -i prod-inventory prod-playbook.yml
把所有環境都定義在同一份 inventory file
[test]
127.0.0.1 ansible_port=2222 ansible_user=test_user

[devl]
127.0.0.1 ansible_port=3333 ansible_user=devl_user

[prod]
127.0.0.1 ansible_port=4444 ansible_user=prod_user
根據環境的不同來定義一些變數
[test]
127.0.0.1 ansible_port=2222 ansible_user=test_user

[test:vars]
email_receivers=test@gmail.com

[devl]
127.0.0.1 ansible_port=2222 ansible_user=devl_user

[devl:vars]
email_receivers=devl@gmail.com

關於 inventory file 更進一步的寫法,可以參考這份官方文件。撰寫清楚的 inventory file 不但能夠讓我們在使用 Ansible 管理 managed node 的過程中更清楚操作對象的資訊,以大幅降低人為疏失的的機率,也能夠有效提升我們進行部署工作時的效率。

配置 PRIVATE_KEY_FILE

PRIVATE_KEY_FILE
fatal: [127.0.0.1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n", "unreachable": true}
to retry, use: --limit @/Users/tsoliang/Desktop/workspace/playbook.retry

從上面的錯誤訊息中我們可以知道部署失敗的原因發生在 SSH 連線失敗

→ Ansible 操作 managed node 必須要透過 SSH 連線嗎?預設將產生出來的公用金鑰 (public key) 存放在 ~/.ssh/ 的路徑下,然後再手動將這組金鑰加到我們想要授權的服務列表 (authorized_keys) 上。不過,因為我們是使用 Vagrant 建立起一台虛擬主機作為練習,Vagrant 其實已經事先幫我們把控制主機與遙控節點做好 SSH 配對了,所以我們並不需要手動設定這個部分。從上面的 vagrant ssh-config 輸出的結果中,我們可以看到一個特殊的參數

vagrant ssh-config
IdentityFile /Users/tsoliang/Desktop/workspace/.vagrant/machines/server/virtualbox/private_key

這個參數告訴了我們這台虛擬主機 private key 的存放位置,我們只需要透過以下指令,將這個檔案的路徑指定給 Ansible,我們就可以成功運行我們的 playbook 囉!

ansible-playbook
--private-key /Users/tsoliang/Desktop/workspace/.vagrant/machines/server/virtualbox/private_key
-i inventory playbook.yml
PLAY [server] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [127.0.0.1]

TASK [test connection] *********************************************************
ok: [127.0.0.1]

TASK [print debug message] *****************************************************
ok: [127.0.0.1] => {
"msg": {
"changed": false,
"failed": false,
"ping": "pong"
}
}

PLAY RECAP *********************************************************************
127.0.0.1 : ok=3 changed=0 unreachable=0 failed=0

大功告成!我們成功接收到從 server 回傳回來的 "pong" 了!在未來的章節內,我們還會介紹如何透過 ansible.cfg 這個檔案的設定來告訴 Ansible SSH 金鑰以及 inventory file 的位置,來讓整個部署流程看起來更加簡潔也讓開發人員更易維護。

配置 ansible.cfg

可以透過配置 Ansible 的組態檔案 ansible.cfg,來指定 Ansible 要去哪裡查找 role 的路徑

在工作目錄新增一個檔案 ansible.cfg 並加入以下內容

ansible.cfg
[defaults]
roles_path = /path/to/roles

如此一來,Ansible 除了預設查找路徑外,還會依此指定路徑去找到我們 role 的存放位置。假設有多個 role 路徑需要設定,我們還可以透過 : 來串接不同 role 的存放路徑

ansible.cfg
[defaults]
roles_path = /path/to/public_roles:/path/to/private_roles

ansible.cfg 還可以做什麼

若點進官方配置文件的說明頁面,可以發現除了 roles_path 之外還有一大堆參數可以依據使用者的需求進行非常有彈性的配置。還記得我們在之前的章節中,必須要在運行 ansible-playbook 的時候同時加上 -i 以及 --private-key 的參數來告訴 Ansible 我們的 inventory file 跟 SSH 金鑰的存放位置嗎?我們並不想要在每次運行都要輸入這一大串資料,因此我們可以在 ansible.cfg 裡定義 inventory 跟 private_key_file 來方便我們管理這類資訊

ansible.cfg
[defaults]
private_key_file = /path/to/private_key
inventory = /path/to/inventory
roles_path = /path/to/roles

將 ansible.cfg 這個配置檔案置於我們工作資料夾之下,目前具體資料夾結構如下:

資料夾結構
workspace
├─ Vagrantfile
├─ ansible.cfg
├─ inventory
├─ playbook.yml
└─ roles
└─ pip
└─ tasks
└─ main.yml

從官方文件中可以發現除了將配置檔案放置於工作目錄底下外,還有其他幾種不同的配置方式:

  1. 設置環境變量 (ANSIBLE_CONFIG)
  2. 置於當前目錄下的 ansible.cfg(這次範例中使用的方法)
  3. 置於根目錄下的 .ansible.cfg
  4. 置於 /etc/ansible/ 下的 ansible.cfg